package day20180912.SampleFactory;

import java.io.IOException;
import java.util.Properties;

public class SampleFactory {

    /**简单工厂模式
     * 通过简单的逻辑判断生成对象
     * 工厂类时整个模式的关键，包含了必要的逻辑判断根据外界给定的信息决定应该创建哪个对象
     * 优点：通过使用工厂类外界可以直接创建具体的对象，而不用管这些对象是如何被创建的。
     * @param type
     * @return
     */
    public static Human makeHuman(String type) {

        if (type.equals("Man")) {
            Man man = new Man();
            man.say();
            return man;
        } else if (type.equals("woman")) {
            Woman woman = new Woman();
            woman.say();
            return woman;
        }else {
            System.out.println("生成不出来");
            return null;
        }
    }

    /**
     * 通过反射的方式创建
     * 优点：不用修改代码，如果我在传入child类，那么就需要去通过逻辑判断new一个child，通过
     * 反射就可以直接传入类名，直接进行调用实现了解耦。
     * @param c
     * @return
     */
    public static Human makePeople(Class c) {
        Human human = null;

        try {
            human =(Human) Class.forName(c.getName()).newInstance();
            System.out.println("通过反射创建对象");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            System.out.println("不支持抽象类和接口");
        } catch (ClassNotFoundException e) {
            System.out.println("找不到类");
        }
        return human;
    }

    /**
     * 读取配置文件创建工厂模式
     * @param classId
     * @return
     */
    public static Human make(String classId) {

        Properties properties = new Properties();

        try {
            properties.load(SampleFactory.class.getResourceAsStream("beans.properties"));

        } catch (IOException e) {
            System.out.println("读取配置文件失败");
            e.printStackTrace();
        }

        //从配置文件中获取类的全名
        String className = (String) properties.get(classId);
        Human human = null;

        //通过反射进行创建
        try {
            Class c = Class.forName(className);
            human = (Human) c.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return human;
    }
}
